var fs = require('fs');
var config = require('../../../config.json');
var ProjectProxy = require('../../../proxy/project.js');
var RepositoryAPI = require('./../local_repositories.js');
var EventProxy = require('eventproxy');
var zip = require('../../../common/zip.js');
var path = require('path');
var _ = require('lodash');
var logger = require('log4js').getLogger();
var request = require('request');
var readline = require('readline');
var waterfall = require('async-waterfall');
var removeDir = require('../../../common/removeDir.js');
var decompress = require('decompress');
var decompressUnzip = require('decompress-unzip');
var uuid = require('uuid');
var platform = require('os').platform();
var child_process = require('child_process');
var execSync = child_process.execSync;
var getTargetDirs = require('./dirs.js').getTargetDirs;
var WorkspaceProxy = require('../../../proxy/workspace.js');
var workspace_dirs = require('./dirs.js').workspace_dirs;
var fireWorkspaceUpdate = require('./notify.js').fireWorkspaceUpdate;
var notifyEnzyme = require('./notify.js').notifyEnzyme;
var compress_suffix_zip = ".zip";

var copyTarget = function (workspace, call_back) {
    var work_name = workspace.work_name;
    var full_name = "workspace" + work_name;
    var project_id = workspace.project_id;
    var root = config.workspace.workspeces_path;
    var target_root = path.join(root, full_name, workspace_dirs.Target);
    var temp_Path = path.join(root, full_name, workspace_dirs.goods_temp);

    fs.exists(temp_Path, function (exists) {
        if (exists) {
            removeDir.remove(temp_Path, function (err) {//删除旧的依赖
                if (err) {
                    logger.info("删除残留goods失败");
                    return call_back(err);
                }
                logger.info("删除残留goods成功");
            });
        }
        fs.mkdir(temp_Path, function (err) {
            if (err) {
                return call_back(err);
            }
            logger.info("创建target目录成功");
            ProjectProxy.getProjectById(project_id, function (err, project) {
                if (err) {
                    return call_back(err);
                }
                var dependencies = project.dependencies;
                _.remove(dependencies, function (n) {
                    return n.status <= 1;
                })
                var fileArray = [];
                var epp = new EventProxy();
                epp.after('push_file', dependencies.length, function () {
                    //从本地仓库拷最新商品到临时文件夹
                    RepositoryAPI.copyList(temp_Path, fileArray, function () {
                        logger.info("拷最新商品到临时文件成功");
                        var dirs = getTargetDirs();
                        //删除旧的依赖
                        removeDir.remove(target_root, function (err) {
                            if (err) {
                                return call_back(err);
                            }
                            var epm = new EventProxy();
                            epm.after('mkdir_target', dirs.length, function () {
                                logger.info("删除旧依赖，创建新依赖成功");
                                call_back();
                            });
                            //创建新的依赖文件夹
                            dirs.map(function (dir, i) {
                                fs.mkdirSync(path.join(root, full_name, dir));
                                epm.emit('mkdir_target');
                            });
                        });
                    })
                });
                dependencies.map(function (dependency, i) {
                    if (dependency.type == config.workspace.goods_type.core_java) {
                        fileArray.push(dependency.name + "_" +
                            dependency.goods_version +
                            compress_suffix_zip);
                    } else {
                        fileArray.push(dependency.name + "_" +
                            dependency.goods_version +
                            compress_suffix_zip);
                    }
                    epp.emit('push_file');
                });
            });
        });
    });
}

exports.copyTarget = copyTarget;

/**
 * 解压的全部是mk商品，mk商品里包含好多压缩的mk产品
 * @param dependencies
 * @param work_name
 * @param call_back
 */
exports.unzip_target = function (dependencies, work_name, call_back) {
    var copydepen = [];
    dependencies.map(function (depen, i) {
        copydepen.push(depen);
    });
    var mk_dependencies = _.remove(copydepen, function (n) {
        return n.type == config.workspace.goods_type.MK && n.status > 1;
    });
    var full_name = "workspace" + work_name;
    var ep = new EventProxy();
    ep.fail(call_back);
    ep.after('unzip_target', mk_dependencies.length, function (errList) {
        _.remove(errList, function (n) {
            return typeof (n) == "undefined";
        })
        if (errList.length > 0) {
            call_back(errList);
        } else {
            call_back(null);
        }
    });
    mk_dependencies.map(function (dependency, i) {
        var goods_path = path.join(config.workspace.workspeces_path, full_name,
            workspace_dirs.goods_temp, dependency.name + "_" +
            dependency.goods_version + compress_suffix_zip);
        var dir_path = path.join(config.workspace.workspeces_path, full_name,
            workspace_dirs.goods_temp, dependency.name);
        fs.exists(dir_path, function (exists) {
            if (!exists) {
                fs.mkdir(dir_path, function (err) {
                    if (err) {
                        call_back(err);
                        return;
                    }
                    decompress(goods_path, dir_path, {
                        plugins: [
                            decompressUnzip()
                        ]
                    }).then(function (data) {
                        if (data.length == 0) {
                            ep.emit("unzip_target", "解压文件出错");
                        } else {
                            ep.emit("unzip_target");
                        }
                    });
                });
            }
        });
    });
}

/**
 * 商品直接按分类解压到目标文件
 * @param dependencies
 * @param work_name
 * @param call_back
 */
exports.distributeDepen = function (dependencies, work_name, call_back) {
    var full_name = "workspace" + work_name;
    var target_path = "";

    _.remove(dependencies, function (n) {
        return n.status <= 1;
    })

    var epd = new EventProxy();
    epd.after('distribute_depen', dependencies.length, function (errList) {
        _.remove(errList, function (n) {
            return typeof (n) == "undefined";
        })
        if (errList.length > 0) {
            call_back(errList);
        }
        call_back(null);
    });
    dependencies.map(function (dependency, i) {
        //mk商品是多个mk产品集合，读取临时解压目录，然后再逐个解压
        if (dependency.type == config.workspace.goods_type.MK) {
            var dir_path = path.join(config.workspace.workspeces_path,
                full_name, workspace_dirs.goods_temp, dependency.name);
            fs.readdir(dir_path, function (err, array) {
                if (err) {
                    return call_back(err);
                }
                var epc = new EventProxy();
                epc.after('copy_depen', array.length, function (errList) {
                    var err = _.remove(errList, function (n) {
                        return typeof (n) == "undefined";
                    })
                    if (errList.length > 0) {
                        call_back(errList);
                    }
                    epd.emit('distribute_depen');
                });
                array.map(function (filename, i) {
                    //解压文件
                    decompress(path.join(dir_path, filename), path.join(config.workspace.workspeces_path,
                        full_name, workspace_dirs.Target), {
                        plugins: [
                            decompressUnzip()
                        ]
                    }).then(function (data) {
                        if (data.length == 0) {
                            return call_back("解压文件出错");
                        } else {
                            epc.emit('copy_depen');
                        }
                    });
                });
            });
        } else {
            //core_java和core_node商品直接解压
            var dir_path = path.join(config.workspace.workspeces_path,
                full_name, workspace_dirs.goods_temp);

            if (dependency.type == config.workspace.goods_type.core_java) {
                target_path = path.join(workspace_dirs.Target,
                    workspace_dirs.Core, workspace_dirs.Core_Java);
            } else if (dependency.type == config.workspace.goods_type.core_node) {
                target_path = path.join(workspace_dirs.Target,
                    workspace_dirs.Core, workspace_dirs.Core_Node);
            }
            var source_path = path.join(dir_path, dependency.name + "_" +
                dependency.goods_version + compress_suffix_zip);
            //解压文件
            decompress(source_path, path.join(config.workspace.workspeces_path,
                full_name, target_path), {
                plugins: [
                    decompressUnzip()
                ]
            }).then(function (data) {
                if (data.length == 0) {
                    return call_back("解压文件出错");
                } else {
                    epd.emit('distribute_depen');
                }
            });
        }
    });
}

var linkTarget = function (workspace, isWin, callback) {
    var work_name = workspace.work_name;
    //var full_name = "workspace" + work_name;
    var project_id = workspace.project_id;
    var workspaces = config.workspace.workspeces_path;
    var target_root;
    var repo_path = config.local_repo_addr;

    try {
        fs.accessSync(repo_path, fs.R_OK);
    } catch (e) {
        fs.mkdirSync(repo_path);
    }

    //遍历依赖列表
    ProjectProxy.getProjectById(project_id, function (err, project) {
        if (err) {
            return callback(err);
        }
        target_root = path.join(workspaces,project.namespace,project.name, work_name, workspace_dirs.Target);
        var dependencies = project.dependencies;
        _.remove(dependencies, function (n) {  //只对正常状态和有更新状态的依赖进行操作
            return n.status <= 1;
        });
        var fileArray = [];
        var ep = new EventProxy();
        ep.fail(callback);

        ep.after('push_file', dependencies.length, function () {
            fileArray.map(function (dependency) {
                var dirs = [];
                var core_java = config.workspace.goods_type.core_java;
                var core_node = config.workspace.goods_type.core_node;
                var mk = config.workspace.goods_type.MK;
                var nectar_plugin = "app_plugin";
                switch (dependency.type) {
                    case core_java:
                        dirs.push({
                            src_path: path.join(repo_path, dependency.file_name, "bundles"),
                            target_path: path.join(target_root, "core", "java", "bundles")
                        });
                        break;
                    case core_node:
                        dirs.push({
                            src_path: path.join(repo_path, dependency.file_name),
                            target_path: path.join(target_root, "core", "node")
                        });
                        break;
                    case mk:
                        dirs.push({
                            src_path: path.join(repo_path, dependency.file_name, "backend", "dev"),
                            target_path: path.join(target_root, "backend", "dev")
                        });
                        dirs.push({
                            src_path: path.join(repo_path, dependency.file_name, "backend", "prod"),
                            target_path: path.join(target_root, "backend", "prod")
                        });
                        dirs.push({
                            src_path: path.join(repo_path, dependency.file_name, "products"),
                            target_path: path.join(target_root, "products")
                        });
                        break;
                    case nectar_plugin:
                        dirs.push({
                            src_path: path.join(repo_path, dependency.file_name),
                            target_path: path.join(target_root, "nectar_plugin")
                        });
                        break;
                }

                dirs.map(function (dir) {
                    var file_array = fs.readdirSync(dir.src_path);
                    file_array.map(function (filename, i) {
                        //创建符号链接

                        var src = path.join(dir.src_path, filename);
                        var target = path.join(dir.target_path, filename);
                        fs.exists(target, function (exists) {
                            if (exists) {
                                logger.error("make symbolic link failed :" + target + " has existed!");
                                return callback("make symbolic link failed :" + target + " has existed!");
                            }
                        });
                        fs.exists(src, function (exists) {
                            if (exists) {
                                var stat = fs.statSync(src);
                                var cmdStr;
                                if (isWin) {
                                    if (stat.isDirectory()) {
                                        cmdStr = 'mklink /j ' + target + ' ' + src;
                                    }else{
                                        cmdStr = 'mklink ' + target + ' ' + src;
                                    }
                                    execSync(cmdStr);
                                }
                                else {
                                    //if (stat.isDirectory()) {
                                    cmdStr = 'ln -sfT ' + src + ' ' + target;
                                    //}else{
                                    //    cmdStr = 'ln -sfT ' + src + ' ' + target;
                                    //}
                                    execSync(cmdStr);
                                }
                            } else {
                                logger.error("make symbolic link for '" + src + "'failed: no such file!");
                                return callback("make symbolic link for '" + src + "'failed: no such file!");
                            }
                        });

                    });
                    logger.info('linking ' + dir.src_path + ' to ' + dir.target_path + ' completed!');
                });
            });
            callback(null);
        });
        //删除旧的依赖
        fs.exists(target_root, function (exists) {
            var target_dirs = getTargetDirs();
            ep.after('mkdir_target', target_dirs.length, function () {
                dependencies.map(function (dependency) {
                    fileArray.push({
                        file_name: dependency.name + "_" +
                        dependency.goods_version, type: dependency.type
                    });
                    ep.emit('push_file');
                });
            });
            if (exists) {
                removeDir.remove(target_root, function (err) {
                    if (err) {
                        return callback(err);
                    }
                    try {
                        target_dirs.map(function (dir) {
                            fs.mkdirSync(path.join(workspaces, project.namespace,project.name ,work_name, dir));
                            ep.emit('mkdir_target');
                        });
                    } catch (e) {
                        return callback(e);
                    }

                });
            } else {
                try {
                    target_dirs.map(function (dir) {
                        fs.mkdirSync(path.join(workspaces, project.namespace,project.name,work_name, dir));
                        ep.emit('mkdir_target');
                    });
                } catch (e) {
                    return callback(e);
                }
            }

        });

    });
}
exports.linkTarget = linkTarget;
/**
 * 更新工作空间依赖
 * {workspace_id:工作空间id}
 * @param req
 * @param res
 * @param next
 */
exports.downloadTarget = function (req, res, next) {
    res.setHeader("Access-Control-Allow-Origin", "*");//跨域请求时需要
    var work_id = req.body.work_id;
    switch (platform) {
        case 'linux' :
        case 'darwin' :
            link(work_id, false, function (err) {
                if (err) {
                    logger.error(err);
                    res.format_json({}, 500);
                } else {
                    res.format_json({}, 200);
                }
            });
            break;
        case 'win32' :
            link(work_id, true, function (err) {
                if (err) {
                    logger.error(err);
                    res.format_json({}, 500);
                } else {
                    res.format_json({}, 200);
                }
            });
            break;
        default :
            copy(work_id, function (err) {
                if (err) {
                    logger.error(err);
                    res.format_json({}, 500);
                } else {
                    res.format_json({}, 200);
                }
            })
    }

};
exports.copy = function(work_id, call_back) {
    var root = config.workspace.workspeces_path;
    waterfall([
        //1.获取工作空间
        function (cb) {
            WorkspaceProxy.getWorkspaceById(work_id, function (err, workspace) {
                if (err) {
                    logger.error("获取工作空间出错");
                    return call_back(err);
                }
                if (workspace == null) {
                    return call_back("工作空间不存在");
                }
                cb(null, workspace);
            });
        },


        //2.拷贝商品
        function (workspace, cb) {
            copyTarget(workspace, function (err, data) {
                if (err) {
                    logger.error("拷贝商品失败");
                    return call_back(err);
                }
                logger.info("拷贝商品成功");
                cb(null, workspace);
            });
        },
        //3.解压商品
        function (workspace, cb) {
            ProjectProxy.getProjectById(workspace.project_id, function (err, project) {
                if (err) {
                    logger.error("解压商品失败");
                    return call_back(err);
                }
                unzip_target(project.dependencies, workspace.work_name, function (err) {
                    if (err) {
                        logger.error("解压mk商品失败");
                        return call_back(err);
                    }
                    logger.info("解压mk商品成功");
                    cb(null, workspace, project);
                });
            });
        },
        //4.分发商品到指定目录
        function (workspace, project, cb) {
            distributeDepen(project.dependencies, workspace.work_name, function (err) {
                if (err) {
                    logger.error("分发所有商品失败");
                    return call_back(err);
                }
                logger.info("分发所有商品成功");
                cb(null, workspace, project);
            });
        },
        //5.删除临时文件
        function (workspace, project, cb) {
            removeDir.remove(path.join(root, "workspace" + workspace.work_name,
                workspace_dirs.goods_temp), function (err) {
                if (err) {
                    logger.error("删除临时文件失败");
                    return call_back(err);
                }
                logger.info("删除临时文件成功");
                cb(null, workspace, project);
            });
        },
        //6.更新数据库工作空间表
        function (workspace, project, cb) {
            WorkspaceProxy.updateDependency(workspace._id, project.dependencies, function (err) {
                if (err) {
                    logger.error("更新数据库工作空间依赖出错");
                    return call_back(err);
                }
                logger.info("更新数据库工作空间依赖成功");
                cb(null, workspace);
            });
        },
        //7.触发外部监听
        function (workspace, cb) {
            fireWorkspaceUpdate(work_id);
            cb(null, workspace);
        },
        //8.通知Enzyme
        function (workspace, cb) {
            notifyEnzyme(workspace.work_name, function (err) {
                if (err) {
                    //如果是新建工作空间，失败是正常的
                    logger.error(err);
                    logger.info("通知Enzyme失败");
                } else {
                    logger.info("通知Enzyme成功");
                }
                cb(null);
            })
        }
    ], function (err, result) {
        if (err) {
            logger.error(err);
            return call_back("未知的异常，工作空间依赖更新失败");
        }
        call_back(null, "done");
    });
}


//通过创建符号链接的形式更新target

var link = function(work_id, isWin, call_back) {
    //1. 获取工作空间信息
    waterfall([
        //1.获取工作空间
        function (cb) {
            WorkspaceProxy.getWorkspaceById(work_id, function (err, workspace) {
                if (err) {
                    logger.error("获取工作空间出错");
                    return call_back({msg: "获取工作空间出错", error: err});
                }
                if (workspace == null) {
                    return call_back("工作空间不存在");
                }
                cb(null, workspace);
            });
        },
        //2. 根据工作空间依赖名称和类型，在repo中找到对应的依赖文件创建符号链接到工作空间中
        function (workspace, cb) {
            linkTarget(workspace, isWin, function (err, data) {
                if (err) {
                    logger.error("创建符号链接失败");
                    return call_back({msg: "创建符号链接失败", error: err});
                }
                logger.info("依赖创建成功");
                cb(null, workspace);
            });
        },
        function (workspace, cb) {
            ProjectProxy.getProjectById(workspace.project_id, function (err, project) {
                if (err) {
                    logger.error("更新数据库工作空间依赖出错");
                    return call_back({msg: "更新数据库工作空间依赖出错", error: err});
                }
                WorkspaceProxy.updateDependency(workspace._id, project.dependencies, function (err) {
                    if (err) {
                        logger.error("更新数据库工作空间依赖出错");
                        return call_back({msg: "更新数据库工作空间依赖出错", error: err});
                    }
                    logger.info("更新数据库工作空间依赖成功");
                    cb(null, workspace);
                });
            });
        },
        //7.触发外部监听
        function (workspace, cb) {
            fireWorkspaceUpdate(work_id);
            cb(null, workspace);
        },
        //8.通知Enzyme
        function (workspace, cb) {
            notifyEnzyme(workspace.work_name, function (err) {
                if (err) {
                    //如果是新建工作空间，失败是正常的
                    logger.error(err);
                    logger.info("通知Enzyme失败");
                } else {
                    logger.info("通知Enzyme成功");
                }
                cb(null);
            })
        }
    ], function (err, result) {
        if (err) {
            logger.error(err);
            return call_back("未知的异常，工作空间依赖更新失败");
        }
        call_back(null, "done");
    });
};
exports.link = link;
//exports.updateWorkTargetByProject = function (req, res, next) {
//    var task_id = uuid.v1();
//    res.format_json({task_id: task_id}, 200);
//    var project_id = req.body.project_id;
//    var projects = [project_id];
//    WorkspaceProxy.getWorkspacesByProjects(projects, function (err, data) {
//        if (err) {
//            logger.error(err);
//            messageBroker.emit(task_id, {task_id: task_id, body: {}, err: "更新工作空间失败：无法获取工作空间信息"});
//            return false;
//        }
//        if (data.length == 0) {
//            messageBroker.emit(task_id, {task_id: task_id, body: {}, err: "更新工作空间失败：该项目没有创建工作空间"});
//            return false;
//        }
//        var work_id = data[0]._id;
//        //检查操作系统 如果win/darwin/linux 执行link 否则 执行copy
//        //switch (platform) {
//        //    case 'linux' :
//        //    case 'darwin' :
//        //        link(false, function () {
//        //        });
//        //        break;
//        //    case 'win32' :
//        //        link(true, function () {
//        //        });
//        //        break;
//        //    default :
//        copy(work_id, function (err) {
//            if (err) {
//                logger.error(err);
//                messageBroker.emit(task_id, {task_id: task_id, body: {}, err: "更新工作空间失败：依赖分发错误"});
//                return false;
//                //res.status(500);
//                //return res.format_json(null, 500, err);
//            }
//            messageBroker.emit(task_id, {task_id: task_id, body: {msg: "更新工作空间成功"}, err: null});
//            //return res.format_json(null, 200, "success");
//        })
//        //}
//
//    })
//}